home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / mkutil21.zip / SRC / UTIL / FOREACH.C < prev    next >
C/C++ Source or Header  |  1995-02-07  |  5KB  |  217 lines

  1. /****************************************************************************
  2. *
  3. *                                Foreach
  4. *
  5. *                    Copyright (C) 1991 Kendall Bennett.
  6. *                            All rights reserved.
  7. *
  8. * Filename:        $RCSfile: foreach.c $
  9. * Version:        $Revision: 1.3 $
  10. *
  11. * Language:        ANSI C
  12. * Environment:    MS DOS
  13. *
  14. * Description:    Program to execute the same command for a number of
  15. *                different files. The list of files is passed in via a
  16. *                simple text file. We try to fit as many files on the
  17. *                command line as possible (120 chars max for MS DOS
  18. *                compatibility).
  19. *
  20. * $Id: foreach.c 1.3 1994/08/22 11:12:10 kjb Exp $
  21. *
  22. ****************************************************************************/
  23.  
  24. #include <stdio.h>
  25. #include <malloc.h>
  26. #include <process.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29.  
  30. #ifdef __MSDOS__
  31. #include <dir.h>
  32. #endif
  33.  
  34. #define    MAX_FILES        200            /* 200 files maximum                */
  35. #define    MAXLINELEN        120            /* 128 chars to a command line        */
  36.  
  37. #define    true            1
  38. #define    false            0
  39.  
  40. /*------------------------- Global variables ------------------------------*/
  41.  
  42. char    *rcsid = "$Id: foreach.c 1.3 1994/08/22 11:12:10 kjb Exp $";
  43. char    *filenames[MAX_FILES];
  44.  
  45. /* Adjust the size of the default stack and heap so that we dont take
  46.  * up too much memory from the child process. A small stack of 256 bytes
  47.  * should be enough, and a heap of 5k should suffice to hold the list of
  48.  * names to process.
  49.  */
  50.  
  51. extern unsigned    _stklen        = 1024;
  52. extern unsigned _heaplen    = 5*1024;
  53.  
  54. /* Open a file returning true if successful */
  55.  
  56. int openfile(FILE **in,char *filename,char *mode)
  57. {
  58.     if( (*in = fopen(filename,mode) ) == NULL) {
  59.         return false;    /* Open failed                                    */
  60.         }
  61.     else
  62.         return true;    /* Open was successful                            */
  63. }
  64.  
  65. void readfilenames(char *name,char *filenames[],int *numfiles)
  66. /****************************************************************************
  67. *
  68. * Function:        readfilenames
  69. * Parameters:    name        - Name of file to read filenames from
  70. *                filenames[]    - Array to place filenames in
  71. *                numfiles    - Number of filenames read
  72. *
  73. * Description:    Reads the names of the files to translate from the
  74. *                specified file 'name'. We expect each file name to we
  75. *                a whole word on the line and ignore all whitespace.
  76. *
  77. ****************************************************************************/
  78. {
  79.     char    buf[MAXPATH];
  80.     FILE    *f;
  81.  
  82.     *numfiles = 0;
  83.     if (!openfile(&f,name,"rt")) {
  84.         /* Unable to open the file - simply return 0 for number of files
  85.          * to process
  86.          */
  87.         return;
  88.         }
  89.  
  90.     while (!feof(f) && (fscanf(f," %s ",buf) == 1)) {
  91.         filenames[*numfiles] = strdup(buf);
  92.         (*numfiles)++;
  93.         }
  94.  
  95.     fclose(f);
  96. }
  97.  
  98. int main(int argc,char *argv[])
  99. {
  100.     char    prefix[MAXLINELEN];
  101.     char    command[MAXLINELEN],*p;
  102.     char    copypath[MAXLINELEN];
  103.     int        i,numfiles,length,totallength,prefixlength;
  104.     int        copyfrom = false, copyto = false, valid = true;
  105.     int        group = true;
  106.  
  107.     if (strcmp(argv[1],"-nogroup") == 0) {
  108.         group = false;
  109.         argv++;
  110.         argc--;
  111.         }
  112.  
  113.     if (strcmp(argv[1],"-cf") == 0) {
  114.         /* Copy the files from the specified path, process them, and return
  115.          * them to where they were.
  116.          */
  117.         copyfrom = true;
  118.         copyto = true;
  119.         argv++;
  120.         argc--;
  121.         }
  122.     else if (strcmp(argv[1],"-ct") == 0) {
  123.         /* Process the files and move them to the specified path */
  124.         copyto = true;
  125.         argv++;
  126.         argc--;
  127.         }
  128.     else if (strcmp(argv[1],"-cl") == 0) {
  129.         /* Copy the files from the specified path, process them and leave
  130.          * the processed files in the current directory
  131.          */
  132.         copyfrom = true;
  133.         argv++;
  134.         argc--;
  135.         }
  136.  
  137.     if ((copyfrom || copyto)) {
  138.         if (argc != 4)
  139.             valid = false;
  140.         }
  141.     else if (argc != 3)
  142.         valid = false;
  143.  
  144.     if (!valid) {
  145.         printf("Usage: foreach [-nogroup] [-cf|-ct|-cl <path>] \"command\" <filelist>\n\n");
  146.         printf("where <filelist> is the name of a file containing the\n");
  147.         printf("filenames for excute command on. If -nogroup is specified\n");
  148.         printf("the command is executed once for every file in <filelist>, otherwise\n");
  149.         printf("the filenames are grouped together on the command line.\n");
  150.         exit(1);
  151.         }
  152.  
  153.     if ((copyfrom || copyto)) {
  154.         strcpy(copypath,argv[1]);
  155.         argv++;
  156.         argc--;
  157.         }
  158.  
  159.     strcpy(prefix,argv[1]);
  160.     p = prefix;
  161.     while (*p != '\0') {
  162.         if (*p == '\'')
  163.             *p = '"';
  164.         p++;
  165.         }
  166.     prefixlength = strlen(prefix);
  167.     readfilenames(argv[2],filenames,&numfiles);
  168.  
  169.     if (copyfrom) {
  170.         /* Copy the files from the specified path first before executing
  171.          * the command on the files.
  172.          */
  173.  
  174.         for (i = 0; i < numfiles; i++) {
  175.             strcpy(command, copypath);
  176.             strcat(command, "\\");
  177.             strcat(command, filenames[i]);
  178.             spawnlp(P_WAIT, "cp", "cp", command, ".", NULL);
  179.             }
  180.         }
  181.  
  182.     /* Execute command once for every file in the list */
  183.  
  184.     for (i = 0; i < numfiles;) {
  185.         strcpy(command,prefix);
  186.         totallength = prefixlength;
  187.         while (totallength < MAXLINELEN && i < numfiles) {
  188.             if ((length = strlen(filenames[i])) == 0) {
  189.                 i++;
  190.                 continue;
  191.                 }
  192.             if ((totallength += length+1) < MAXLINELEN) {
  193.                 strcat(command," ");
  194.                 strcat(command,filenames[i++]);
  195.                 }
  196.             if (!group)
  197.                 break;
  198.             }
  199.         printf(command);
  200.         printf("\n");
  201.  
  202.         if (system(command)) {
  203.             perror("Command failed");
  204.             exit(1);
  205.             }
  206.         }
  207.  
  208.     if (copyto) {
  209.         /* Copy the processed files to the specified path */
  210.  
  211.         for (i = 0; i < numfiles; i++)
  212.             spawnlp(P_WAIT, "mv", "mv", filenames[i], copypath, NULL);
  213.         }
  214.  
  215.     return 0;
  216. }
  217.